package com.pignest.hotel.beans.global;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.pignest.hotel.beans.User;
import com.pignest.hotel.system.Hotel;

/**
 * 子权限, 权限细分后的子权限
 * */
public final class Permission {
	
	public static final Permission USER_MANAGER = new Permission("USER_MANAGER", "用户管理");
	public static final Permission MEMBER_MANAGER = new Permission("MEMBER_MANAGER", "会员管理");
	public static final Permission ROOM_STATUS = new Permission("ROOM_STATUS", "房间状态");
	public static final Permission ROOM_MANAGER = new Permission("ROOM_MANAGER", "房间管理");
	public static final Permission SETTING = new Permission("SETTING", "基础设置");
	public static final Permission SELF_SERVICE = new Permission("SELF_SERVICE", "自助服务");
	public static final Permission BOOKING = new Permission("BOOKING", "预订房间");
	public static final Permission RECEPTION = new Permission("RECEPTION", "前台接待");
	public static final Permission ACCOUNT_MANAGER = new Permission("ACCOUNT_MANAGER", "账务管理");
	public static final Permission REPORT = new Permission("REPORT", "报表");
	public static final Permission ADMINISTER = new Permission("ADMINISTER", "系统管理");
	
	public static final Permission DENY = new Permission("DENY", null, new Alow() {
		public boolean alow(User user) {
			return false;
		};
	});
	public static final Permission SUPER = new Permission("SUPER", null, new Alow() {
		public boolean alow(User user) {
			return user != null && user.isSuperUser();
		};
	});
	public static final Permission LOGIN = new Permission("LOGIN", null, new Alow() {
		public boolean alow(User user) {
			return user != null && user.isEnable();
		};
	});

	static {
		initPermissions();
	}
	
	private static Map<String, Permission> permissions = new LinkedHashMap<String, Permission>();
	
	/** 权限内部值 */
	public final String name;
	/** 权限显示名 */
	public final String label;

	private final Alow alower;
	private final boolean open;
	
	private Permission parent;
	private List<Permission> children;
	
	private Permission(String name, String label) {
		this.name = name;
		this.label = label;
		this.open = true;
		this.alower = null;
	}
	
	private Permission(String name, String label, Alow alow) {
		this.name = name;
		this.label = label;
		this.open = false;
		this.alower = alow;
	}
	
	public boolean alow(User user) {
		if (Hotel.TEST)
			return true;
		if (this.alower != null)
			return this.alower.alow(user);
		if (user == null)
			return false;
		if (user.isSuperUser())
			return true;
		Collection<String> permissions = user.getPermissions();
		for (String permission : permissions) {
			if (this.name.equals(permission))
				return true;
		}
		return false;
	}
	
	@Override
	public String toString() {
		return label;
	}
	
	private void addSubPermission(String... strs) {
		for (int i = 0; i < strs.length; i += 2) {
			String name = this.name + "." + strs[i];
			Permission p = new Permission(name, strs[i + 1]);
			p.parent = this;
			if (children == null)
				children = new ArrayList<Permission>();
			children.add(p);
			permissions.put(name, p);
		}
	}
	
	private static void initPermissions() {
		permissions.put(USER_MANAGER.name, USER_MANAGER);
		USER_MANAGER.addSubPermission(Key.ADD, "新增用户", Key.EDIT, "编辑用户", Key.DELETE, "删除用户");
		permissions.put(MEMBER_MANAGER.name, MEMBER_MANAGER);
		permissions.put(ROOM_STATUS.name, ROOM_STATUS);
		permissions.put(ROOM_MANAGER.name, ROOM_MANAGER);
		permissions.put(SELF_SERVICE.name, SELF_SERVICE);
		permissions.put(BOOKING.name, BOOKING);
		permissions.put(RECEPTION.name, RECEPTION);
		permissions.put(ACCOUNT_MANAGER.name, ACCOUNT_MANAGER);
		permissions.put(REPORT.name, REPORT);
		permissions.put(ADMINISTER.name, ADMINISTER);
		permissions.put(SETTING.name, SETTING);
		
	}
	
	private interface Alow {
		public boolean alow(User user);
	}
	
	private static class Key {
		public static final String ADD = "ADD";
		public static final String EDIT = "EDIT";
		public static final String DELETE = "DELETE";
//		public static final String VIEW = "DELETE";
		
	}
}
